-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Strip ascriptions originating from PrepareInlineable.wrapRHS or Typer.ensureNoLocalRefs during inlining
#24425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Strip ascriptions originating from PrepareInlineable.wrapRHS or Typer.ensureNoLocalRefs during inlining
#24425
Conversation
|
Isn't that basically making all |
Maybe, and that is probably not what we want. So when should the result of calling a non-transparent inline method actually be visible? [Comment extracted to #24431] |
As discussed orally, no, assuming we put the stripping logic at the right place: in the Inliner, to make sure that we only do it during inlining. |
|
Edit: temporary fixed by 6ae39ef and 8b803e1. Dropping ascriptions has strange effects, making Consider import scala.deriving.*
import scala.compiletime.*
trait ConfigMonoid[T]:
def zero: T
def orElse(main: T, defaults: T): T
object ConfigMonoid:
given option: [T] => ConfigMonoid[Option[T]] = ???
inline def zeroTuple[C <: Tuple]: Tuple =
inline erasedValue[C] match
case _: EmptyTuple => EmptyTuple
case _: (t *: ts) =>
summonInline[ConfigMonoid[t]].zero *: zeroTuple[ts]
inline def valueTuple[C <: Tuple, T](index: Int, main: T, defaults: T): Tuple =
inline erasedValue[C] match
case _: EmptyTuple => EmptyTuple
case _: (t *: ts) =>
def get(v: T) = v.asInstanceOf[Product].productElement(index).asInstanceOf[t]
summonInline[ConfigMonoid[t]].orElse(get(main), get(defaults)) *: valueTuple[ts, T](
index + 1,
main,
defaults
)
inline given derive: [T] => (m: Mirror.ProductOf[T]) => ConfigMonoid[T] =
new ConfigMonoid[T]:
def zero: T = m.fromProduct(zeroTuple[m.MirroredElemTypes])
def orElse(main: T, defaults: T): T = m.fromProduct(valueTuple[m.MirroredElemTypes, T](0, main, defaults))
final case class PublishContextualOptions(
v1: Option[String] = None,
v2: Option[String] = None,
v3: Option[String] = None,
)
object PublishContextualOptions:
implicit val monoid: ConfigMonoid[PublishContextualOptions] = ConfigMonoid.derive // was crashWe get the following error: The def zero: PublishContextualOptions =
m$proxy1.fromProduct(
{
{
val x$1: Option[String] = ConfigMonoid.option[String].zero
{
val Tuple_this: Tuple =
{
{
val x$1: Option[String] =
ConfigMonoid.option[String].zero
{
val Tuple_this: Tuple =
{
{
val x$1: Option[String] =
ConfigMonoid.option[String].zero
{
val Tuple_this: Tuple =
{
EmptyTuple
}:Tuple
runtime.Tuples.cons(x$1, Tuple_this).
asInstanceOf[*:[Option[String], Tuple]]:
*:[Option[String], Tuple]
}
}
}:Tuple
runtime.Tuples.cons(x$1, Tuple_this).asInstanceOf[
*:[Option[String], Tuple]]:
*:[Option[String], Tuple]
}
}
}:Tuple
runtime.Tuples.cons(x$1, Tuple_this).asInstanceOf[
*:[Option[String], Tuple]]:*:[Option[String], Tuple]
}
}
}:TupleAnd with my changes: def zero: PublishContextualOptions =
m$proxy1.fromProduct(
{
{
val x$1: Option[String] = ConfigMonoid.option[String].zero
{
val x$1: Option[String] = ConfigMonoid.option[String].zero
val x$1: Option[String] = ConfigMonoid.option[String].zero
val Tuple_this: EmptyTuple.type = EmptyTuple
val Tuple_this: Option[String] *: Tuple =
runtime.Tuples.cons(x$1, Tuple_this).asInstanceOf[
*:[Option[String], Tuple]]:*:[Option[String], Tuple]
{
val Tuple_this: Option[String] *: Tuple =
runtime.Tuples.cons(x$1, Tuple_this).asInstanceOf[
*:[Option[String], Tuple]]:*:[Option[String], Tuple]
runtime.Tuples.cons(x$1, Tuple_this).asInstanceOf[
*:[Option[String], Tuple]]:*:[Option[String], Tuple]
}
}
}
}
)Which is incorrect. My current guess is that dropping ascriptions enables eliding expressions, which in turns create other problems. Need to further investigate… Note: I tried to narrow the ascriptions stripping to only ascriptions created by |
13d4c32 to
ae88b64
Compare
Bingo, the culprit is |
8e5b86f to
a8240f8
Compare
|
Edit: fixed by 8b803e1. 6ae39ef was incomplete because it lost the capability to inline calls inside blocks, returning The remaining failing test is Minimal reproduction: extension (x: String)
transparent inline def rep(min: Int = 0): String = ???
def y: String = ???
def z = y.rep().toUpperCaseWhen lifting blocks, it fails (as expected?) with a type error: -- [E007] Type Mismatch Error: tests/pos/i18123b.scala:6:8 ---------------------
6 |def z = y.rep().toUpperCase
| ^^^^^^^
|Found: (??? : => Nothing)
|Required: ?{ toUpperCase: ? }
|Note that implicit conversions were not tried because the result of an implicit conversion
|must be more specific than ?{ toUpperCase: <?> }
|
| longer explanation available when compiling with `-explain`But if we don't lift blocks, then we get: -- Error: tests/pos/i18123b.scala:6:8 ------------------------------------------
6 |def z = y.rep().toUpperCase
| ^^^^^^^
| <notype> is illegal as a selection prefixWhich is due to the following adaptation: adapt1(
tree = {
val x$1: String = y
rep(x$1)(i18123b$package.rep$default$2(x$1))
},
pt = ?{ toUpperCase: ? }
) == <empty> |
…lineTyper.typedTyped`
82155ed to
8b803e1
Compare
|
I temporary solved the problems described in my 3 last comments by disabling lifting blocks in Remaining, unrelated test failure: To be investigated. |
PrepareInlineable.wrapRHS or Typer.ensureNoLocalRefs during inlining
Attempt to fix #24420 by removing ascriptions during inlining when they originate from
PrepareInlineable.wrapRHSorTyper.ensureNoLocalRefs.